package com.gradumate.client;

import java.util.logging.Logger;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.gradumate.client.gui.AfstudeercommissieAfstudeerVoorstelDetail;
import com.gradumate.client.gui.GebruikerSelectie;
import com.gradumate.client.gui.StudieAdviseurAfstudeerVerzoekDetail;
import com.gradumate.client.service.GraduMateService;
import com.gradumate.client.service.GraduMateServiceAsync;
import com.gradumate.shared.Gebruiker;
import com.gradumate.shared.LoginToken;
import com.gradumate.shared.MenuFactory;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 * 
 * @param <StudentAfstudeervoorstelIndienen>
 */
public class GraduMate implements EntryPoint {

	// AsyncService
	private GraduMateServiceAsync server = GWT.create(GraduMateService.class);

	// Loading Gif
	private static Image img = new Image();

	// Element
	private static Element element = new Element();

	// MenuFactory
	private static MenuFactory mf;

	// Gebruiker
	private static Gebruiker gebruiker;

	// Logger
	private final static Logger log = Logger.getLogger(GraduMate.class
			.getName());

	/**
	 * Constructor
	 */
	public void onModuleLoad() {
		// Loading gif instellen
		img = element.getImage("Laden..", "ajax-loader.gif");

		// Iemand logt in met een Token
		if (Window.Location.getParameter("t") != null && Window.Location.getParameter("e") != null) {
			
			// Laadschermpje plaatsen
			GraduMate.setLoadingImage(true);

			// Parameters bepalen
			String token = Window.Location.getParameter("t");
			String gebruikerEmail = Window.Location.getParameter("e");

			// Controlleer of de benodigde variabelen gevuld zijn.
			if ((token != null && token.length() > 0) && (gebruikerEmail != null && gebruikerEmail.length() > 0)) {

				// Server aanroepen en Token ophalen
				server.getLoginTokenByTokenAndEmail(token, gebruikerEmail, new AsyncCallback<LoginToken>() {

					public void onFailure(Throwable caught) {
						log.info("Service failure -> getLoginTokenByTokenAndEmail() -> " + caught.getMessage());
						GraduMate.addAsyncError();
					}

					@Override
					public void onSuccess(final LoginToken loginToken) {
						
						// Controleren of er een LoginToken kan worden gevonden, anders functie aanroepen
						if (loginToken != null) {

							// Functie bepalen
							final int function = loginToken.getFunction();
							
							// Aanvrager bepalen
							server.getGebruikerByEmail(loginToken.getGebruikerEmail(), new AsyncCallback<Gebruiker>() {
								@Override
								public void onFailure(Throwable caught) {
									log.info("Service failure -> getGebruikerByEmail() -> " + caught.getMessage());
									GraduMate.addAsyncError();
								}

								@Override
								public void onSuccess(Gebruiker aanvrager) {									
									GraduMate.setGebruiker(aanvrager);
									
									server.getGebruikerByEmail(loginToken.getStudentEmail(), new AsyncCallback<Gebruiker>() {

										@Override
										public void onFailure(Throwable caught) {
											log.info("Service failure -> getGebruikerByEmail() -> " + caught.getMessage());
											GraduMate.addAsyncError();
										}

										@Override
										public void onSuccess(Gebruiker student) {
											
											// Bijbehordende functie opvragen
											switch (function) {
												case 1:
													new AfstudeercommissieAfstudeerVoorstelDetail(student, loginToken);
												break;
												
												case 2:
													new StudieAdviseurAfstudeerVerzoekDetail(student, loginToken);
												break;
											}
										}
									});
								}
							});
						} else {
							// Nieuw gebruiker selectie aanroepen
							new GebruikerSelectie();
						}
					}
				});
			} else {
				// Nieuw gebruiker selectie
				new GebruikerSelectie();
			}

		} else {
			// Nieuw gebruiker selectie.
			new GebruikerSelectie();
		}
	}

	/**
	 * Plaatst een draaiend gifje om het laden van de pagina aan te geven.
	 * 
	 * @param Boolean
	 *            of het plaatje getoond moet worden of niet
	 */
	public static void setLoadingImage(boolean show) {

		RootPanel.get("main").clear();

		if (show) {
			FlexTable table = new FlexTable();
			table.setCellSpacing(20);
			table.setWidget(0, 1, img);
			table.setWidget(0, 0, new Label("  Laden.."));
			RootPanel.get("main").add(table);
		}
	}

	/**
	 * Stelt de gebruiker in.
	 * 
	 * @param Gebruiker
	 *            g.
	 */
	public static void setGebruiker(Gebruiker g) {

		log.info("Cache aanleggen: " + g.getGebruikerEmail());
		gebruiker = g;

		mf = new MenuFactory();
		mf.refreshMenuBar(g);
	}

	/**
	 * Stuurt de gebruiker terug
	 * 
	 * @return Gebruiker g
	 */
	public static Gebruiker getGebruiker() {
		return gebruiker;
	}

	/**
	 * Verwijderd de status berichten van de RootPanel
	 */
	public static void clearStatusMessages() {
		// Controleren er al een status word getoond, anders weghalen
		if (RootPanel.get("error").isAttached())
			RootPanel.get("error").clear();
		if (RootPanel.get("success").isAttached())
			RootPanel.get("success").clear();
		if (RootPanel.get("information").isAttached())
			RootPanel.get("information").clear();
	}

	/**
	 * Toont een foutmelding
	 * 
	 * @param String
	 *            msg met het te vertonen bericht
	 */
	public static void addErrorMsg(String msg) {
		GraduMate.clearStatusMessages();
		RootPanel.get("error").add(element.errorTable(msg));
	}

	/**
	 * Toont een success melding
	 * 
	 * @param String
	 *            msg met het te vertonen bericht
	 */
	public static void addSuccessMsg(String msg) {
		GraduMate.clearStatusMessages();
		RootPanel.get("success").add(element.successTable(msg));
	}

	/**
	 * Toont een informatie bericht
	 * @param String msg met het te vertonen bericht.
	 */
	public static void addInformationMsg(String msg) {
		GraduMate.clearStatusMessages();
		RootPanel.get("information").add(element.informationTable(msg));
	}

	/**
	 * Toont een foutmelding dat er iets mis ging met de server communicatie
	 */
	public static void addAsyncError() {
		GraduMate.addErrorMsg("Er ging iets mis bij de communicatie met de server, probeer het later opnieuw.");
	}
}
